#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <omp.h>
#include "preprocessor.h"

int main(int argc, char * args[]) {


    FILE *pFile;
    node *words = NULL;
    node *words2 = NULL;
    node *words5 = NULL;
    node *words10 = NULL;
    node *words15 = NULL;
    node *words20 = NULL;
    node *words25 = NULL;

    node *words2_5 = NULL;
    node *words2_10 = NULL;
    node *words2_15 = NULL;
    node *words2_20 = NULL;
    node *words2_25 = NULL;


    node* aux_sub;
    int i, j, counter_wordTotal = 0, counter_wordParcial = 0, words_size[46] = {0};

    words = preProcessor(&counter_wordTotal, words_size, &words5, &words10, &words15, &words20, &words25);

    row *a;
    row b;
    
    puts("até aqui");
    initRow(&b);
    insertRow(&b, "asd");
    insertRow(&b, "asd");
    
    initRow(&a);
    insertRow(&a, "dsa");
    insertRow(&a, "asd");
    
    printRow(b);
    printRow(&(*words5->rowSub));

    printf("nó %s, numero de blocos %d\n", words5->word, words5->blocks);
    printf("nó %s, numero de blocos %d\n", words10->left->word, words->left->blocks);


    printf("\ndepois %d\n", counter_wordTotal);
    pFile = fopen("res_word_3.txt", "w");
    int n, w;
    char c;
    int th_id, flag = 0, porcent = 0;




#pragma omp parallel private(th_id,i,j)
    {       

//         int r;
//         th_id = omp_get_thread_num();
//         srand(time(NULL) * th_id);
//         n = rand();
//         printf("rand = %d\n", n);
// 
//         if (th_id % 2 == 0) // versao 2
//         {
//                     node* aux;
//         node* aux_tree;
//             char chars[28] = {'e', 't', 'a', 'o', 'i', 'n', 's', 'h', 'r', 'd',
//                 'l', 'c', 'u', 'm', 'w', 'f', 'g', 'y', 'p', 'b', 'v', 'k', 'j',
//                 'x', 'q', 'z', '{'};
//             char ch;
//             int size_word = 0;
// 
//             for (j = 0; 1; j++) {
//                 if (flag > 1000000) {
//                     srand(time(NULL) * th_id);
//                     r = rand() % 27;
// 
//                     for (w = 0; w < 27; w++)
//                         chars[w] = ((chars[w] - 'a') + r) % 27 + 'a';
// 
//                     //           printf("1: mudou seed na thread %d\n novo alfabeto %s \n",th_id,chars);
//                     flag = 0;
//                 }
// 
//                 char s[50] = {0};
//                 int val = j;
//                 node *aux = NULL;
//                 size_word = 0;
// 
//                 for (i = 0; i < 100; i++) {
//                     flag++;
// 
//                     if (findN(s, words, i) == NULL)
//                         i = 99;
// 
// 
//                     ch = chars[val % 27];
//                     s[i] = ch;
//                     val = val / 27;
// 
// #pragma omp critical                 
//                     aux = find(s, words5);
//                     if (aux != NULL) {
//                         if (find(s, words2_5) == NULL) {
// 
//                             flag = 0;
//                             words2_5 = insert(s, words2_5);
// 
//                             while (aux->rowSub) {
// 
//                                 aux_tree = findSub(getRowNode(aux), words, 0);
//                                 //                               printf("pedaco %s, completo %s\n",s,aux->word);
//                                 if (aux_tree->complete) {
//                                     fprintf(pFile, "%s\n", aux_tree->word);
// //                                     printf("0 encontrou inteira: %s\n",aux_tree->word);
// 
//                                     counter_wordParcial++;
//                                 }
// 
//                             }
// 
//                             if (porcent != (counter_wordParcial * 100) / counter_wordTotal) {
// 
//                                 porcent = (counter_wordParcial * 100) / counter_wordTotal;
//                                 printf("total %d encontrados %d porcentagem %d th_id %d j %d i %d\n", counter_wordTotal, counter_wordParcial,
//                                         (counter_wordParcial * 100) / counter_wordTotal, th_id, j, i);
//                             }
// 
//                             //                             fprintf(pFile, "%s\n", s);
// 
//                         }
//                     }
// 
// #pragma omp critical                 
//                     aux = find(s, words15);
//                     if (aux != NULL) {
//                         if (find(s, words2_15) == NULL) {
// 
//                             flag = 0;
//                             words2_15 = insert(s, words2_15);
// 
//                             while (aux->rowSub) {
//                                 //                               display_avl_row(aux);
//                                 aux_tree = findSub(getRowNode(aux), words, 1);
// 
//                                 //                               printf("pedaco %s, completo %s\n",s,aux->word);
//                                 if (aux_tree->complete) {
//                                     fprintf(pFile, "%s\n", aux_tree->word);
// //                                     printf("5 encontrou inteira: %s\n", aux_tree->word);
//                                     counter_wordParcial++;
//                                 }
// 
//                             }
// 
//                             if (porcent != (counter_wordParcial * 100) / counter_wordTotal) {
// 
//                                 porcent = (counter_wordParcial * 100) / counter_wordTotal;
//                                 printf("total %d encontrados %d porcentagem %d th_id %d j %d i %d\n", counter_wordTotal, counter_wordParcial,
//                                         (counter_wordParcial * 100) / counter_wordTotal, th_id, j, i);
//                             }
// 
//                             //                             fprintf(pFile, "%s\n", s);
//                         }
//                     }
// 
// #pragma omp critical                 
//                     aux = find(s, words10);
//                     if (aux != NULL) {
//                         if (find(s, words2_10) == NULL) {
// 
//                             flag = 0;
//                             words2_10 = insert(s, words2_10);
// 
//                             while (aux->rowSub) {
//                                 //                               display_avl_row(aux);
//                                 aux_tree = findSub(getRowNode(aux), words, 2);
// 
//                                 //                               printf("pedaco %s, completo %s\n",s,aux->word);
//                                 if (aux_tree->complete) {
//                                     fprintf(pFile, "%s\n", aux_tree->word);
// //                                     printf("10 encontrou inteira: %s\n", aux_tree->word);
//                                     counter_wordParcial++;
//                                 }
// 
//                             }
// 
//                             if (porcent != (counter_wordParcial * 100) / counter_wordTotal) {
// 
//                                 porcent = (counter_wordParcial * 100) / counter_wordTotal;
//                                 printf("total %d encontrados %d porcentagem %d th_id %d j %d i %d\n", counter_wordTotal, counter_wordParcial,
//                                         (counter_wordParcial * 100) / counter_wordTotal, th_id, j, i);
//                             }
// 
//                             //                             fprintf(pFile, "%s\n", s);
//                         }
//                     }
// 
// 
// 
//                     if (counter_wordParcial == counter_wordTotal)
//                         exit(0);
//                 }
//             }
//         } else // versao 1
        {        node* aux;
        node* aux_tree;
            char chars[28] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
                'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
                'x', 'y', 'z', '{'};
            int r;
            th_id = omp_get_thread_num();

            srand(time(NULL) * th_id);
            chars[27] = '\0';

            while (1) {
                char s[50] = {0};

                if (flag > 100000) {
                    srand(time(NULL) * th_id);
                    //             printf("2: mudou seed na thread %d\n novo alfabeto %s \n",th_id,chars);
                    flag = 0;
                    r = rand() % 27;

                    for (w = 0; w < 27; w++)
                        chars[w] = ((chars[w] - 'a') + r) % 27 + 'a';

                }

                for (i = 1; i <= 100; i++) {
                    flag++;

                    for (j = 1; j <= i; j++) {

                        n = rand() % 27;
                        c = chars[n];
                        s[j - 1] = c;

                        if (findN(s, words, j) == NULL)
                            j = i;

#pragma omp critical                 
                    aux = find(s, words5);
                    if (aux != NULL) {
                        if (find(s, words2_5) == NULL) {

                                                  
                            flag = 0;
                            words2_5 = insert(s, words2_5);

//                             if(strcmp("brute",s) == 0);
//                                printRow(&(*aux->rowSub));
//                             if(strcmp("like",s)==0)
//                                printRow(&(*aux->rowSub));
                            while (aux->rowSub!= NULL) {

                                aux_tree = findSub(getRowNode(aux), words, 0);
                                //                               printf("pedaco %s, completo %s\n",s,aux->word);
                                if (aux_tree->complete) {
                                    fprintf(pFile, "%s\n", aux_tree->word);
//                                     printf("0 encontrou inteira: %s\n",aux_tree->word);

                                    counter_wordParcial++;
                                }

                            }
//                             if(porcent >= 38)
//                                   printf("10 encontrou inteira: %s parcial %d porcent %d\n", aux_tree->word,counter_wordParcial,porcent);

                            if (porcent != (counter_wordParcial * 100) / counter_wordTotal) {

                                porcent = (counter_wordParcial * 100) / counter_wordTotal;
                                printf("total %d encontrados %d porcentagem %d th_id %d j %d i %d\n", counter_wordTotal, counter_wordParcial,
                                        (counter_wordParcial * 100) / counter_wordTotal, th_id, j, i);
                            }

                            //                             fprintf(pFile, "%s\n", s);

                        }
                    }


#pragma omp critical                 
                    aux = find(s, words10);
                    if (aux != NULL) {
                        if (find(s, words2_10) == NULL) {

                            flag = 0;
                            words2_10 = insert(s, words2_10);
                            
                            while (aux->rowSub) {

                                aux_tree = findSub(getRowNode(aux), words, 1);

                                //                               printf("pedaco %s, completo %s\n",s,aux->word);

                                if(strcmp("like",s)==0)
                                  display_avl_blocks(aux_tree);
                                
//                                 puts(aux_tree->word);
                                if (aux_tree->complete) {
                                  if(strcmp("brutelike",s)==0)
                                    puts("brutelike");

                                  fprintf(pFile, "%s\n", aux_tree->word);
//                                     printf("10 encontrou inteira: %s\n", aux_tree->word);
                                    counter_wordParcial++;
                                }

                            }
//                             if(porcent >= 38)
//                                   printf("10 encontrou inteira: %s parcial %d porcent %d\n", aux_tree->word,counter_wordParcial,porcent);

                            if (porcent != (counter_wordParcial * 100) / counter_wordTotal) {

                                porcent = (counter_wordParcial * 100) / counter_wordTotal;
                                printf("total %d encontrados %d porcentagem %d th_id %d j %d i %d\n", counter_wordTotal, counter_wordParcial,
                                        (counter_wordParcial * 100) / counter_wordTotal, th_id, j, i);
                            }

                            //                             fprintf(pFile, "%s\n", s);
                        }
                    }

#pragma omp critical                 
                    aux = find(s, words15);
                    if (aux != NULL) {
                        if (find(s, words2_15) == NULL) {

                            flag = 0;
                            words2_15 = insert(s, words2_15);
        

                              
                            while (aux->rowSub) {
                                //                               display_avl_row(aux);
                                aux_tree = findSub(getRowNode(aux), words, 2);

//                                                               printf("pedaco %s, completo %s\n",s,aux_tree->word);
                                
                                if (aux_tree->complete) {
                                    fprintf(pFile, "%s\n", aux_tree->word);
//                                     printf("5 encontrou inteira: %s\n", aux_tree->word);
                                    counter_wordParcial++;
                                }
                                
                            }
//                             if(porcent >= 38)
//                                   printf("10 encontrou inteira: %s parcial %d porcent %d\n", aux_tree->word,counter_wordParcial,porcent);

                            if (porcent != (counter_wordParcial * 100) / counter_wordTotal) {

                                porcent = (counter_wordParcial * 100) / counter_wordTotal;
                                printf("total %d encontrados %d porcentagem %d th_id %d j %d i %d\n", counter_wordTotal, counter_wordParcial,
                                        (counter_wordParcial * 100) / counter_wordTotal, th_id, j, i);
                            }

                            //                             fprintf(pFile, "%s\n", s);
                        }
                    }
                    
                    #pragma omp critical                 
                    aux = find(s, words20);
                    if (aux != NULL) {
                        if (find(s, words2_20) == NULL) {

                            flag = 0;
                            words2_20 = insert(s, words2_20);

                            while (aux->rowSub!= NULL) {
                                //                               display_avl_row(aux);
                                aux_tree = findSub(getRowNode(aux), words, 3);

                                //                               printf("pedaco %s, completo %s\n",s,aux->word);
                                if (aux_tree->complete) {
                                    fprintf(pFile, "%s\n", aux_tree->word);
                                    printf("encontrou inteira: %s\n", aux_tree->word);
                                    counter_wordParcial++;
                                }

                            }
//                             if(porcent >= 38)
//                                   printf("10 encontrou inteira: %s parcial %d porcent %d\n", aux_tree->word,counter_wordParcial,porcent);

                            if (porcent != (counter_wordParcial * 100) / counter_wordTotal) {

                                porcent = (counter_wordParcial * 100) / counter_wordTotal;
                                printf("total %d encontrados %d porcentagem %d th_id %d j %d i %d\n", counter_wordTotal, counter_wordParcial,
                                        (counter_wordParcial * 100) / counter_wordTotal, th_id, j, i);
                            }

                            //                             fprintf(pFile, "%s\n", s);
                        }
                    }

#pragma omp critical                 
                    aux = find(s, words25);
                    if (aux != NULL) {
                        if (find(s, words2_25) == NULL) {

                            flag = 0;
                            words2_25 = insert(s, words2_25);

                            while (aux->rowSub) {
                                //                               display_avl_row(aux);
                                aux_tree = findSub(getRowNode(aux), words, 4);

                                //                               printf("pedaco %s, completo %s\n",s,aux->word);
                                if (aux_tree->complete) {
                                    fprintf(pFile, "%s\n", aux_tree->word);
                                    printf("encontrou inteira: %s\n", aux_tree->word);
                                    counter_wordParcial++;
                                }

                            }
//                             if(porcent >= 38)
//                                   printf("10 encontrou inteira: %s parcial %d porcent %d\n", aux_tree->word,counter_wordParcial,porcent);

                            if (porcent != (counter_wordParcial * 100) / counter_wordTotal) {

                                porcent = (counter_wordParcial * 100) / counter_wordTotal;
                                printf("total %d encontrados %d porcentagem %d th_id %d j %d i %d\n", counter_wordTotal, counter_wordParcial,
                                        (counter_wordParcial * 100) / counter_wordTotal, th_id, j, i);
                            }

                            //                             fprintf(pFile, "%s\n", s);
                        }
                    }
                    


                            if (counter_wordParcial == counter_wordTotal)
                                exit(0);
                        }
                    }
                }
            }
        
    }
    fclose(pFile);







    return 0;
}


